The present invention relates to compiling software. More specifically, the invention relates to techniques for reducing the cost of dynamic (i.e., during runtime) class loading and initialization checks in compiled code.
The Java.TM. programming language is an object-oriented high level programming language developed by Sun Microsystems and designed to be portable enough to be executed on a wide range of computers ranging from small devices (e.g., pagers, cell phones and smart cards) up to supercomputers. Computer programs written in Java (and other languages) may be compiled into virtual machine instructions for execution by a Java virtual machine. In general the Java virtual machine is an interpreter that decodes and executes the virtual machine instructions.
The virtual machine instructions for the Java virtual machine are bytecodes, meaning they include one or more bytes. The bytecodes are stored in a particular file format called a "class file" that includes bytecodes for methods of a class. In addition to the bytecodes for methods of a class, the class file includes a symbol table as well as other ancillary information.
A computer program embodied as Java bytecodes in one or more class files is platform independent. The computer program may be executed, unmodified, on any computer that is able to run an implementation of the Java virtual machine. The Java virtual machine is a software emulator of a "generic" computer that is a major factor in allowing computer programs for the Java virtual machine to be platform independent.
The Java virtual machine may be implemented as a software interpreter. Conventional interpreters decode and execute the virtual machine instructions of an interpreted program one instruction at a time during execution, which is in contrast to compilers that decode source code into native machine instructions prior to execution so that decoding is not performed during execution. The Java virtual machine may include both an interpreter and compiler for runtime compilation. Typically, the Java virtual machine will be written in a programming language other than the Java programming language (e.g., the C++ programming language).
At runtime compilation, a Java method may access (for either reading or writing) field of a class that has not been loaded. A Java virtual machine that is compiling the virtual machine instructions into native machine instructions at runtime to increase runtime performance may not have all the information available at the time of compilation. For example, if a class is not loaded then it is difficult, if not impossible, to determine the offset for an instance variable within an instance of the class.
One solution to the problem of unavailable runtime execution information is to generate native machine instructions that check to see if a class is loaded and initialized before fields of classes are accessed. In practice, this solution may do much more harm than good. The runtime checks may degrade the performance of the system much more than the compilation increases the performance.
Another solution to the problem of unavailable runtime execution information would be to load, and possibly initialize, any classes to which runtime execution information is required to compile the virtual machine instructions. Although this may seem like a good solution, it may unnecessarily slow down the system if at runtime execution it is not necessary to load the class. For example, if a statement that modifies a field of an instance of class A is only executed if X=0, then class A may be lazily loaded when X=0 (assuming class A will not be loaded for other reasons). Additionally, it is semantically incorrect to unnecessarily initialize a class because the Java runtime environment is designed to dynamically load classes at runtime only when they are needed.